package edu.lingnan.myrule;

import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.AbstractLoadBalancerRule;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.Server;

import java.util.List;
import java.util.concurrent.ThreadLocalRandom;

/**
 * @author wuyuan
 * @since 2020-06-09 15:28
 */
public class WuyuanRandomRule extends AbstractLoadBalancerRule{
        public WuyuanRandomRule() {
        }
//        每个服务都访问5次，然后换下一个服务（目前只有3个）

        /**
         * 算法设计：
         *  total=0（初始化）：被访问次数
         *  currentIndex=0（初始化）：当前是哪个节点在提供服务
         *  如果total累加到5，currentIndex++，则指向下一个服务节点；
         */
        private int total = 0;
        private int currentIndex = 0;

        @SuppressWarnings({"RCN_REDUNDANT_NULLCHECK_OF_NULL_VALUE"})
        public Server choose(ILoadBalancer lb, Object key) {
            if (lb == null) {
                return null;
            } else {
                Server server = null;

                while(server == null) {
                    if (Thread.interrupted()) {
                        return null;
                    }

                    List<Server> upList = lb.getReachableServers(); // 获取或着的服务
                    List<Server> allList = lb.getAllServers(); //获取全部的服务（死的、活的）
                    int serverCount = allList.size();
                    if (serverCount == 0) {
                        return null;
                    }

                    /*int index = this.chooseRandomInt(serverCount); //生成区间随机数
                    server = (Server)upList.get(index); // 从活着的服务中随机获取一个*/

//                -----------------------------------------

//                    改写策略算法
                    if (total < 5){
                        server = upList.get(currentIndex);
                        total++;
                    } else {
                        total = 0;
                        currentIndex++;
                        if (currentIndex >= upList.size()){
                            currentIndex = 0;
                        }
                        server = upList.get(currentIndex); // 从活着的服务列表中获取指定的服务进行访问
                    }

 //                -----------------------------------------

                    if (server == null) {
                        Thread.yield();
                    } else {
                        if (server.isAlive()) {
                            return server;
                        }

                        server = null;
                        Thread.yield();
                    }
                }

                return server;
            }
        }

        protected int chooseRandomInt(int serverCount) {
            return ThreadLocalRandom.current().nextInt(serverCount);
        }

        @Override
        public Server choose(Object key) {
            return this.choose(this.getLoadBalancer(), key);
        }

        @Override
        public void initWithNiwsConfig(IClientConfig clientConfig) {
        }
    }
